#include <stdlib.h>
#include <assert.h>
#include "edge.h"
#include "node.h"


/*! @struct s_edge 
 *  @brief Esta estructura es utilizada para representar las aristas de los networks.
 *  @param nd Nodo
 *  @param capacity Capacidad de la arista
 *  @param flow  Flujo circulante por la arista
 *  @param backward Booleano que indica el sentido del uso de la arista en el camino.
 */
struct s_edge {
	node nd;
	unsigned int capacity; 
	unsigned int flow; 
    bool backward; 
};

edge edge_create(node nd, unsigned int capacity, unsigned int flow, 
                bool backward){
	edge e = NULL;
    assert(nd != NULL);
	e = (edge) malloc(sizeof(struct s_edge));
	if (e != NULL){
        e-> nd = nd;
        e-> capacity = capacity;
        e-> flow = flow;
        e-> backward = backward;
	}
	return e;
}

unsigned int edge_get_capacity(edge e){
	assert (e != NULL);
    return e->capacity;
}

void edge_set_capacity(edge e, unsigned int capacity){
    e->capacity = capacity;
}

unsigned int edge_get_flow(edge e){
	assert (e != NULL);
    return e->flow;
}

void edge_set_flow(edge e, unsigned int flow){
    assert (e != NULL);
    e->flow = flow;
}

bool edge_get_backward(edge e){
	assert (e != NULL);
    return e->backward;
}

void edge_set_backward(edge e, bool status ){
    assert (e != NULL);
    e->backward = status;
}

node edge_to(edge e){
	assert (e != NULL);
    return e->nd;
    
}

edge edge_destroy(edge e){
    assert(e!=NULL);
	free(e);
	return NULL;
}

edge edge_find_node_forw(node x, node y){
    unsigned int name = 0;
    plist_t neighbours = NULL;
    edge e = NULL;
    
    assert(x!=NULL);
    assert(y!=NULL);
    
    name = node_name(x);
    neighbours = node_neighbours(x);
    plist_rewind(neighbours);
    e = plist_get_next(neighbours);
    
    /* Recorro los vecinos del nodo x hasta encontrar al y */
    while (e != NULL){
            if (node_name(y) == node_name(edge_to(e)) && 
                !edge_get_backward(e)){
                
                /* Si lo encuentro devuelvo la arista*/
                return e;                
            }
        e = plist_get_next(neighbours);
    }
    
    /* Si no esta devolvemos NULL*/
    return NULL;
}

edge edge_find_node_back(node x, node y){
    unsigned int name = 0;
    plist_t neighbours = NULL;
    edge e = NULL;
    
    assert(x!=NULL);
    assert(y!=NULL);
    
    name = node_name(x);
    neighbours = node_neighbours(x);
    plist_rewind(neighbours);
    e = plist_get_next(neighbours);
    
    /* Recorro los vecinos del nodo x hasta encontrar al y */
    while (e != NULL){
            if (node_name(y) == node_name(edge_to(e)) 
                && edge_get_backward(e)){
                
                /* Si lo encuentro devuelvo la arista*/
                return e;                
            }
        e = plist_get_next(neighbours);
    }
    
    /* Si no esta devolvemos NULL*/
    return NULL;
}
    
    
    

